import java.util.Date;

import processing.core.PApplet;
import processing.core.PConstants;
import processing.core.PFont;
import processing.core.PImage;


public class Tooltip {
	private PApplet parent = null;
	private IssuePlayerProject ipp = null;
	
	private long startTime = 0;
	
	private boolean showTooltip = false;
	
	private Issue currentIssue = null;
	private Issue lockedIssue = null;
	private String issueDetails = "";
	
	private User currentUser = null;
	private User lockedUser = null;

	private PFont fontTooltipHeading = null;
	private PFont fontTooltipValue = null;
	private PFont fontDetails = null;

	private String tooltipValue = "";
	private int TOOLTIPBGSTROKE = 0;
	private int TOOLTIPBGFILL = 0;
	private int TOOLTIPTEXTSTROKE = 0;
	private int TOOLTIPTEXTFILL = 0;

	// Text Coordinates and Colors
	private PImage defaultImage = null;
	
	private int PICX = 0;
	private int PICY = 0;
	private int USERIDX = 0;
	private int USERIDY = 0;
	private int USERSTATUSX = 0;
	private int USERSTATUSY = 0;
	private int CURRENTISSUESX = 0;
	private int CURRENTISSUESY = 0;
	private int USERNAMEX = 0;
	private int USERNAMEY = 0;
	private int REALNAMEX = 0;
	private int REALNAMEY = 0;

	
	private int ISSUEIDX = 0;
	private int ISSUEIDY = 0;
	private int ISSUESTATUSX = 0;
	private int ISSUESTATUSY = 0;
	private int RESOLUTIONX = 0;
	private int RESOLUTIONY = 0;
	private int CATEGORYX = 0;
	private int CATEGORYY = 0;
	private int PRIORITYX = 0;
	private int PRIORITYY = 0;
	private int SUBMITTEDBYX = 0;
	private int SUBMITTEDBYY = 0;
	private int ASSIGNEDTOX = 0;
	private int ASSIGNEDTOY = 0;
	private int OPENDATEX = 0;
	private int OPENDATEY = 0;
	private int CLOSEDATEX = 0;
	private int CLOSEDATEY = 0;
	
	private int FIELDSTROKE = 0;
	private int FIELDFILL = 0;
	private int INFOSTROKE = 0;
	private int INFOFILL = 0;

	// BG Rect Coordinates and Colors
	private int BGX1 = 0;
	private int BGY1 = 0;
	private int BGX2 = 0;
	private int BGY2 = 0;
	private int BGSTROKE = 0;
	private int BGFILL = 0;
	
	private boolean showBackground = false;
	private boolean showDetails = false;
	
	public Tooltip(PApplet p, IssuePlayerProject i) {
		this.parent = p;
		this.ipp = i;
		this.fontTooltipHeading = parent.createFont("FFScalaBold", 14);
		this.fontTooltipValue = parent.createFont("FFScala", 12);
		this.fontDetails = parent.createFont("FFScala", 12);
		this.defaultImage = this.parent.loadImage("default.jpg");
		setup();
	}

	public void setup() {
		BGSTROKE = parent.color(0,0,0);
		BGFILL = parent.color(255,255,255);
		TOOLTIPBGSTROKE = parent.color(155,155,155);
		TOOLTIPBGFILL = parent.color(155,155,155);
		TOOLTIPTEXTSTROKE = parent.color(0,0,0);
		TOOLTIPTEXTFILL = parent.color(0,0,0);
		FIELDSTROKE = parent.color(100);
		FIELDFILL = parent.color(100);
		INFOSTROKE = parent.color(255,255,255);
		INFOFILL = parent.color(255,255,255);
	}

	public void setStartTime(long time) {
		startTime = time;
	}
	
	public boolean isOver() {
		if(BGX1 <= parent.mouseX && parent.mouseX <= BGX2 && BGY1 <= parent.mouseY && parent.mouseY <= BGY2)
			return true;
		
		return false;
	}
	
	public boolean isDetails() {
		return showDetails;
	}
	
	public boolean isLocked() {
		return (lockedIssue != null) || (lockedUser != null);
	}
	
	public void update(int x1, int y1, int x2, int y2, boolean showDet, boolean showBack) {
		// Don't Modify These
		BGX1 = x1;
		BGY1 = y1;
		BGX2 = x2;
		BGY2 = y2;
		showDetails = showDet;
		showBackground = showBack;

		// First Row for Users
		USERIDX = BGX2-(fontTooltipHeading.twidth*20);
		USERIDY = BGY1+20;
		USERSTATUSX = USERIDX+(fontTooltipHeading.twidth*5);
		USERSTATUSY = USERIDY;

		// Second Row for Users
		USERNAMEX = USERIDX;
		USERNAMEY = USERIDY+(fontTooltipHeading.theight*3);
		CURRENTISSUESX = USERNAMEX+(fontTooltipHeading.twidth*5);
		CURRENTISSUESY = USERNAMEY;

		// Third Row for Users
		REALNAMEX = USERIDX;
		REALNAMEY = USERNAMEY+(fontTooltipHeading.theight*3);

		// Picture for Users
		PICX = USERIDX - 5;
		PICY = BGY1 + (PICX-BGX1);
		if(PICY > (REALNAMEY+fontTooltipHeading.theight)) {
			PICY = REALNAMEY+fontTooltipHeading.theight;
			PICX = BGX1+(PICY-BGY1);
		}

		// First Row for Issues
		int center = BGX1 + (BGX2-BGX1)/2;
		ISSUEIDX = center-(fontTooltipHeading.twidth*9);
		ISSUEIDY = BGY1+20;
		ISSUESTATUSX = center-(fontTooltipHeading.twidth*3);
		ISSUESTATUSY = ISSUEIDY;
		RESOLUTIONX = center+(fontTooltipHeading.twidth*3);
		RESOLUTIONY = ISSUEIDY;
		CATEGORYX = center+(fontTooltipHeading.twidth*9);
		CATEGORYY = ISSUEIDY;

		// Second Row for Issues
		PRIORITYX = center-(fontTooltipHeading.twidth*6);
		PRIORITYY = ISSUEIDY+(fontTooltipHeading.theight*3);
		SUBMITTEDBYX = center;
		SUBMITTEDBYY = PRIORITYY;
		ASSIGNEDTOX = center+(fontTooltipHeading.twidth*6);
		ASSIGNEDTOY = PRIORITYY;

		// Third Row for Issues
		OPENDATEX = center-(fontTooltipHeading.twidth*3);
		OPENDATEY = PRIORITYY+(fontTooltipHeading.theight*3);
		CLOSEDATEX = center+(fontTooltipHeading.twidth*3);
		CLOSEDATEY = OPENDATEY;		
	}
	
	public void setValue(int value) {
		tooltipValue = new Integer(value).toString();
		showTooltip = true;
	}
	
	public void setValue(String value) {
		tooltipValue = value;
		showTooltip = true;
	}

	public void setValue(Issue value) {
		currentIssue = value;
		currentUser = null;
		tooltipValue = new Integer(value.getId()).toString();
		showTooltip = true;
	}

	public void setValue(User value) {
		currentUser = value;
		currentIssue = null;
		tooltipValue = value.getRealName();
		showTooltip = true;
	}

	public void setLockedValue(Issue value) {
		lockedUser = null;

		if(lockedIssue != value) {
		lockedIssue = value;
		issueDetails = ipp.getDetails(value);
		} else
			lockedIssue = null;
	}
	
	public void setLockedValue(User value) {
		lockedIssue = null;

		if(lockedUser != value)
			lockedUser = value;
		else
			lockedUser = null;
	}

	public void displayLockedOnly() {
		if(lockedIssue != null)
			displayIssue(lockedIssue);
		else if(lockedUser != null)
			displayUser(lockedUser);
	}
	
	public void displayIssue(Issue iss) {
		if(showBackground) {
			parent.stroke(BGSTROKE);
			parent.fill(BGFILL);
			parent.rect(BGX1, BGY1, BGX2, BGY2);
		}
		
		parent.rectMode(PConstants.CORNERS);
		parent.stroke(FIELDSTROKE);
		parent.fill(FIELDFILL);
		parent.rect(BGX1, BGY1, BGX2, BGY2);
		
		parent.stroke(INFOSTROKE);
		parent.fill(INFOFILL);
		parent.textFont(fontTooltipHeading);
		parent.textAlign(PConstants.CENTER);//, PConstants.BOTTOM);
		parent.text("Issue ID:", ISSUEIDX, ISSUEIDY);
		parent.text("Status:", ISSUESTATUSX, ISSUESTATUSY);
		parent.text("Resolution:", RESOLUTIONX, RESOLUTIONY);
		parent.text("Category:", CATEGORYX, CATEGORYY);
		parent.text("Priority:", PRIORITYX, PRIORITYY);
		parent.text("Submitted By:", SUBMITTEDBYX, SUBMITTEDBYY);
		parent.text("Assigned To:", ASSIGNEDTOX, ASSIGNEDTOY);
		parent.text("Open Date:", OPENDATEX, OPENDATEY);
		if(iss.getCloseDate() > 0)
			parent.text("Close Date:", CLOSEDATEX, CLOSEDATEY);

		parent.textFont(fontTooltipValue);
		parent.text(iss.getId(), ISSUEIDX, ISSUEIDY+fontTooltipHeading.theight);
		parent.text(iss.getStatus(), ISSUESTATUSX, ISSUESTATUSY+fontTooltipHeading.theight);
		parent.text(iss.getResolution(), RESOLUTIONX, RESOLUTIONY+fontTooltipHeading.theight);
		parent.text(iss.getCategory(), CATEGORYX, CATEGORYY+fontTooltipHeading.theight);
		parent.text(iss.getPriority(), PRIORITYX, PRIORITYY+fontTooltipHeading.theight);
		parent.text(iss.getSubmittedBy().getUserName(), SUBMITTEDBYX+5, SUBMITTEDBYY+fontTooltipHeading.theight);
		parent.text(iss.getAssignedTo().getUserName(), ASSIGNEDTOX+5, ASSIGNEDTOY+fontTooltipHeading.theight);
		parent.text(formatDate(new Date(iss.getOpenDate()*24*60*60*1000 + startTime)), OPENDATEX, OPENDATEY+fontTooltipHeading.theight);
		if(iss.getCloseDate() > 0)
			parent.text(formatDate(new Date(iss.getCloseDate()*24*60*60*1000 + startTime)), CLOSEDATEX, CLOSEDATEY+fontTooltipHeading.theight);			
			
		if(showDetails) {
			parent.textFont(fontDetails);
			parent.textAlign(PConstants.LEFT, PConstants.TOP);
			parent.text(issueDetails, BGX1+5, CLOSEDATEY+(fontTooltipHeading.theight*2), BGX2-5, BGY2);
		}
	}
	
	public void displayUser(User user) {
		if(showBackground) {
			parent.stroke(BGSTROKE);
			parent.fill(BGFILL);
			parent.rect(BGX1, BGY1, BGX2, BGY2);
		}
		
		parent.rectMode(PConstants.CORNERS);
		parent.stroke(FIELDSTROKE);
		parent.fill(FIELDFILL);
		parent.rect(BGX1, BGY1, BGX2, BGY2);
		
		parent.stroke(INFOSTROKE);
		parent.fill(INFOFILL);
		parent.textFont(fontTooltipHeading);
		parent.textAlign(PConstants.LEFT);//, PConstants.BOTTOM);
		parent.text("User ID:", USERIDX, USERIDY);
		parent.text("Status:", USERSTATUSX, USERSTATUSY);
		parent.text("Current Issues:", CURRENTISSUESX, CURRENTISSUESY);
		parent.text("User Name:", USERNAMEX, USERNAMEY);
		parent.text("Real Name:", REALNAMEX, REALNAMEY);

		parent.textFont(fontTooltipValue);
		parent.text(user.getId(), USERIDX, USERIDY+fontTooltipHeading.theight);
		parent.text(user.getStatus(), USERSTATUSX, USERSTATUSY+fontTooltipHeading.theight);
		parent.text(user.getIssueCount(), CURRENTISSUESX, CURRENTISSUESY+fontTooltipHeading.theight);
		parent.text(user.getUserName(), USERNAMEX, USERNAMEY+fontTooltipHeading.theight);
		parent.text(user.getRealName(), REALNAMEX, REALNAMEY+fontTooltipHeading.theight);

		parent.imageMode(PConstants.CORNERS);
		if(user.getImage() != null)
			parent.image(user.getImage(), BGX1, BGY1, PICX, PICY);
		else if(defaultImage != null)
			parent.image(defaultImage, BGX1, BGY1, PICX, PICY);			
	}

	public void display() {
		// Draw Tooltip
		if(showTooltip) {
			parent.stroke(TOOLTIPBGSTROKE);
			parent.fill(TOOLTIPBGFILL);
			parent.rect(parent.mouseX, parent.mouseY-fontTooltipValue.theight, parent.mouseX+(fontTooltipValue.twidth*tooltipValue.length()), parent.mouseY);
			parent.stroke(TOOLTIPTEXTSTROKE);
			parent.fill(TOOLTIPTEXTFILL);
			parent.textFont(fontTooltipValue);
			parent.textAlign(PConstants.CENTER, PConstants.BOTTOM);
			parent.text(tooltipValue, parent.mouseX+(fontTooltipValue.twidth*tooltipValue.length())/2, parent.mouseY);

			if(currentIssue != null)
				displayIssue(currentIssue);
			
			if(currentUser != null)
				displayUser(currentUser);

			showTooltip = false;
		} else {
			if(lockedIssue != null)
				displayIssue(lockedIssue);
			else if(lockedUser != null)
				displayUser(lockedUser);
		}
	}

	@SuppressWarnings("deprecation")
	private String formatDate(Date d) {
		String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"};
		return months[d.getMonth()] + " " + d.getDate() + ", " + (d.getYear()+1900);
	}

}
